package com.xhwl.centiotdata.repair;

import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationFactory;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationHandler;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.pojo.enums.pedestrian.PedestrianMethodEnum;
import com.xhwl.centiotdata.service.RepairDetailLogService;
import com.xhwl.centiotdata.service.RepairOperateLogService;
import com.xhwl.centiotdata.service.integrateconfig.PedestrianIntegrationConfig;
import com.xhwl.centiotdata.utils.ThreadPoolUtils;
import com.xhwl.common.dto.cent.iotdata.repair.RepairActionDTO;
import com.xhwl.common.enums.iot.RepairResultEnum;
import com.xhwl.common.enums.iot.RepairStepResultEnum;
import com.xhwl.common.enums.iot.RepairTypeEnum;
import com.xhwl.common.pojo.cent.iot.RepairOperateLog;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.utils.CalendarUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Copyright (C),1998-2022, 兴海物联
 * FileName: PedestriansSyncManager
 * Author: XuChang
 * Date: 2022/8/7 23:16
 * Description: 人行修复管理类
 * History:
 */
@Component
public class PedestriansSyncManager {

    RepairContext repairContext;

    RepairOperateLogService repairOperateLogService;

    RepairDetailLogService repairDetailLogService;

    PedestrianIntegrationConfig integrationConfig;

    //每一个任务超时时间，单位s
    private static final int TIMEOUT_LIMIT = 30;


    @Autowired
    public void setRepairOperateLogService(RepairOperateLogService repairOperateLogService) {
        this.repairOperateLogService = repairOperateLogService;
    }

    @Autowired
    public void setRepairDetailLogService(RepairDetailLogService repairDetailLogService) {
        this.repairDetailLogService = repairDetailLogService;
    }

    @Autowired
    public void setIntegrationConfig(PedestrianIntegrationConfig integrationConfig) {
        this.integrationConfig = integrationConfig;
    }

    @Autowired
    public void setRepairContext(RepairContext repairContext) {
        this.repairContext = repairContext;
    }

    public String start(Integer type, RepairActionDTO repairActionDTO, Account account) {
        IRepairTask iRepairTask = repairContext.getTask(type);
        if (iRepairTask == null) {
            return "不支持的修复类型";
        }
        // 获取到需要执行拉取人行出入记录的项目及配置
        Object config = iRepairTask.getConfig(repairActionDTO);
        if (config == null) {
            return "未找到对应同步配置";
        }
        //初始化操作记录
        RepairOperateLog repairOperateLog = repairOperateLogService.initOperate(repairActionDTO, account);
        if (repairOperateLog == null) {
            return "生成操作日志失败，请联系管理员";
        }
        Integer taskId = repairOperateLog.getId();
        //首先生成详情日志
        List<Date> list = repairDetailLogService.generateDetailLog(repairActionDTO, taskId);
        if (list == null) {
            return "生成操作详情日志失败，请联系管理员";
        }
        //超时时间，是任务数量*TIMEOUT_LIMIT s
        repairOperateLogService.delayCheckTimeOut(list.size() * TIMEOUT_LIMIT, taskId);
        List<Boolean> repairResult = new ArrayList<>();

        list.stream().forEach(date -> ThreadPoolUtils.baiLianSyncExecutor.execute(() -> {
            try {
                repairDetailLogService.updateStatus(taskId, date, RepairStepResultEnum.INVOKING, null, null);
                String error = iRepairTask.repairAction(date, config);
                if (error != null) {  //失败
                    setResult(repairResult, list.size(), false, taskId, date, null, error);
                } else {
                    setResult(repairResult, list.size(), true, taskId, date, null, "修复成功！");
                }
            } catch (Exception e) {
                e.printStackTrace();
                setResult(repairResult, list.size(), false, taskId, date, null, e.getMessage());
            }
        }));
        return null;
    }

    //修改任务状态
    private void setResult(List<Boolean> repairResult, int size, boolean success, Integer taskId, Date date, String resultLog, String operateLog) {
        if (success) {
            repairDetailLogService.updateStatus(taskId, date, RepairStepResultEnum.SUCCESS, resultLog, operateLog);
        } else {
            repairDetailLogService.updateStatus(taskId, date, RepairStepResultEnum.FAILED, resultLog, operateLog);
        }
        repairResult.add(success);
        //代表任务执行结束
        if (repairResult.size() == size) {
            if (!repairResult.contains(true)) {  //全部失败
                repairOperateLogService.updateOperateResult(RepairResultEnum.FAILED, taskId);
            } else if (!repairResult.contains(false)) {  //全部失败
                repairOperateLogService.updateOperateResult(RepairResultEnum.SUCCESS, taskId);
            } else {   //部分失败
                repairOperateLogService.updateOperateResult(RepairResultEnum.LOST, taskId);
            }
        }
    }
}
